#include <iostream>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include<thread>
#include <atomic> 
#include"ThreadPool.h"
using namespace std;

//这里是用了线程池的服务器，但是没有用epoll，效率极低
//处理几十并发的qps都仅仅只有几十
//但这里利用cpp atomic 添加了计数器 ， atomic天生是线程安全的，
//有助于对服务器的监控，可以用到后面去
atomic<int> active_connections(0);
atomic<int> total_connections(0);
atomic<long> total_bytes(0);

void sendfile(int a)  // 输出发送响应报文
{
    active_connections++;
    total_connections++;
    auto start_time = chrono::high_resolution_clock::now();

    struct timeval timeout;
    timeout.tv_sec=10; //10秒超时
    timeout.tv_usec=0;//0微秒超时
    const char* response = 
        "HTTP/1.1 200 OK\r\n"
        "Server: VerySimpleServer\r\n"
        "Content-Type: text/plain; charset=UTF-8\r\n"
        "Connection: keep-alive\r\n"
        "Content-Length: 10\r\n"
        "\r\n"
        "0123456789";  // 10字节内容
    
    send(a, response, strlen(response), 0);
    auto end_time = chrono::high_resolution_clock::now();
    auto duration = chrono::duration_cast<chrono::milliseconds>(end_time - start_time);
    cout << "连接处理时间: " << duration.count() << "ms" << endl;
    
    active_connections--;
}

//处理客户端链接
void handleclient(int client_fd,struct sockaddr_in client_addr)
{
    active_connections++;
    total_connections++;
    auto start_time = chrono::high_resolution_clock::now();

    struct timeval timeout;
    timeout.tv_sec=10; //10秒超时
    timeout.tv_usec=0;//0微秒超时

    if(setsockopt(client_fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout))<0)
    {
        cout<<"setsockopt error"<<endl;
    }

    cout << "New client connected from "
         << inet_ntoa(client_addr.sin_addr) << ":"
         << ntohs(client_addr.sin_port) << endl;
    cout<<"client_fd: "<<client_fd<<endl;
    cout<<"this thread id : "<<this_thread::get_id()<<endl;
    // 这里可以添加与客户端通信的代码

    string wm="Hello,Client";
    send(client_fd, "Hello,Client", 13, 0);
    while (true)
    {
        char buffer[1024] = {0};
        int ret = recv(client_fd, buffer, sizeof(buffer), 0);
        if (ret > 0)
        {
            total_bytes += ret;
            cout << "Received from client: " << buffer << endl;
            send(client_fd, buffer, ret, 0);
        }
        else if (ret == 0)
        {
            cout << "Client disconnected" << endl;
            break;
        }
        else
        {
            if(errno==EAGAIN||errno==EWOULDBLOCK)
            {
                cout<<"recv timeout/ client name: "<<client_fd<<endl;
                break;
            }
            else
            {
                cout << "recv error" << endl;
                break;
            }
        }
    }
    auto end_time = chrono::high_resolution_clock::now();
    auto duration = chrono::duration_cast<chrono::milliseconds>(end_time - start_time);
    cout << "连接处理时间: " << duration.count() << "ms" << endl;
    
    active_connections--;
    close(client_fd);
}

void print_stats() {
    while(true) {
        cout << "\n=== 服务器统计 ===" << endl;
        cout << "活动连接数: " << active_connections << endl;
        cout << "总连接数: " << total_connections << endl;
        cout << "总传输字节: " << total_bytes << endl;
        cout << "=================" << endl;
        
        this_thread::sleep_for(chrono::seconds(5));
    }
}

int main()
{
    thread stats_thread(print_stats);
    stats_thread.detach();
    
    // 创建socket
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0)
    {
        cout << "socket error" << endl;
        return -1;
    }

    // 配置服务器地址
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8080);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    // INADDR_ANY表示接受任意IP地址的链接,自动去读本地网卡的IP地址
    cout << "addr.sin_addr.s_addr: " << addr.sin_addr.s_addr << endl;
    // 绑定地址和端口
    if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
    {
        cout << "bind error" << endl;
        close(fd);
        return -1;
    }
    cout << "bind success" << endl;
    // 设置监听
    if (listen(fd, 5) < 0)
    {
        cout << "listen error" << endl;
        close(fd);
        return -1;
    }

    cout << "Server is listening on port 8080..." << endl;

    // 接受客户端连接
    struct sockaddr_in client_addr;
    socklen_t client_len = sizeof(client_addr);
    
    ThreadPool pool(2);

    while (true)
    {
        int client_fd = accept(fd, (struct sockaddr *)&client_addr, &client_len);
        if (client_fd < 0)
        {
            cout << "accept error" << endl;
            continue;
        }
        
       // pool.addTaks(handleclient,client_fd,client_addr);
        //t.detach(); //分离线程 后台运行
        auto obj=std::bind(sendfile,client_fd);
        pool.addTaks(obj);
    }

    close(fd);
    return 0;
}